package com.android.webrtc.audio;

import android.util.Log;

public class VoiceActivityDetector {
	static {
        System.loadLibrary("webrtc_aecm"); // to load the libwebrtc_aecm.so library
    }
	
	public static final int VAD_MILD = 0;
	public static final int VAD_MIDDLE = 1;
	public static final int VAD_HIGH = 2;
	public static final int VAD_SUPERHIGH = 3;
	
	private int vadHandle = 0;
	
	public VoiceActivityDetector() throws Exception {
		this.vadHandle = vadCreate();
		if (this.vadHandle < 0)
			throw new Exception("Cannot create vad handle");
		if (0 != vadInit(this.vadHandle))
			throw new Exception("Cannot init vad");
	}
	
	public void setMode(int mode) {
		if (mode != VAD_MILD && mode != VAD_MIDDLE &&
				mode != VAD_HIGH && mode != VAD_SUPERHIGH)
			throw new IllegalArgumentException();
		
		if (this.vadHandle <= 0)
			throw new IllegalStateException("Handle not valid");
		
		if (0 != vadSetMode(this.vadHandle, mode))
			Log.e("VoiceActivityDetector", "Cannot set mode");
	}
	
	// Return true for active voice
	public boolean process(int freq, short []audioFrame) throws Exception {
		if (this.vadHandle <= 0)
			throw new IllegalStateException("Handle not valid");
		
		int ret = vadProcess(this.vadHandle, freq, audioFrame, audioFrame.length);
		if (ret < 0)
			throw new Exception("Cannot process: " + ret);
		
		return ret == 1;
	}
	
	public void close() {
		if (this.vadHandle <= 0)
			throw new IllegalStateException("Handle not valid");
		
		if (0 != vadFree(this.vadHandle))
			Log.e("VAD", "Cannot free vad handle: " + this.vadHandle);
		
		this.vadHandle = 0;
	}
	
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
	
		if (this.vadHandle > 0)
			vadFree(this.vadHandle);
	}
	
	private static native int vadCreate();
	private static native int vadFree(int vadHandle);
	private static native int vadInit(int vadHandle);
	private static native int vadSetMode(int vadHandle, int mode);
	private static native int vadProcess(int vadHandle,
			int freq, short []audio_frame, int frameLength);
	private static native int vadValidRateAndFrameLength(
			int rate, int frameLength);
}
